#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <yirae/ylist.h>

extern FILE *yyin;

char* parser_get_remote_ip();
int parser_get_remote_port();
char* parser_get_local_ip();
yList parser_get_local_ports();

struct _ConfigFile {
	int port;
	char* remote_ip;
	char* local_ip;
	yList ports;
};

typedef struct _ConfigFile *ConfigFile;

static ConfigFile _configfile_open(const char *);
static void _configfile_verify_exit(ConfigFile cf);
static ConfigFile _configfile_new();


void configfile_free(ConfigFile cf)
{
	free(cf);
}

ConfigFile configfile_new(const char *fname)
{
	ConfigFile cf = _configfile_open(fname);
	_configfile_verify_exit(cf);
	return cf;
}


int configfile_get_port(ConfigFile cf)
{
	if(!cf) {
		return 0;
	}

	return cf->port;
}

char* configfile_get_ip_remote(ConfigFile cf)
{
	if(!cf) {
		return NULL;
	}

	return cf->remote_ip;
}

char* configfile_get_ip_local(ConfigFile cf)
{
	if(!cf) {
		return NULL;
	}

	return cf->local_ip;
}

yList configfile_get_ports(ConfigFile cf)
{
	if(!cf) {
		return NULL;
	}

	return cf->ports;
}


/*privates*/
static ConfigFile _configfile_new()
{
	ConfigFile cf = calloc(1, sizeof(struct _ConfigFile));
	if(!cf) {
		return NULL;
	}

	cf->port = 0;
	cf->remote_ip = NULL;
	cf->local_ip = NULL;
	cf->ports = NULL;
	return cf;
}

static ConfigFile _configfile_open(const char *fname)
{

	yyin = fopen(fname, "r");
	if(!yyin) {
		return NULL;
	}

	yyparse();

	fclose(yyin);

	ConfigFile cf = _configfile_new();
	if(!cf) {
		return NULL;
	}

	cf->port = parser_get_remote_port();
	cf->remote_ip = parser_get_remote_ip();
	cf->local_ip = parser_get_local_ip();
	cf->ports = parser_get_local_ports();

	return cf;
}

static void _configfile_verify_exit(ConfigFile cf)
{
	int ok = 0xf;

	if(cf->port == -1) {
		fprintf(stderr, "Remote port MUST be set in config file\n");
		ok &= 0xd;
	}

	if(ylist_length(cf->ports) == 1 && ylist_int_get(cf->ports, 0) == -1) {
		fprintf(stderr, "Local ports list MUST be set in config file\n");
		ok &= 0xc;
	}

	if(!cf->remote_ip) {
		fprintf(stderr, "Remote IP MUST be set in config file\n");
		ok &= 0xb;
	}

	if(!cf->local_ip) {
		fprintf(stderr, "Local IP MUST be set in config file\n");
		ok &= 7;
	}

	if(ok != 0xf) {
		exit(EXIT_FAILURE);
	}
}

